var DynamicMenu = {
	$categoriesContainer: 		$("#profile-sidebar-menu"),
	$swipeInContainer: 			$("#swipe-in-container"),
	$swipeOutContainer:			$("#swipe-out-container"),
	backlinksArray:				[],
	$backlinkHTML:				$('<li><a class="back-to" href="#summary"><span>name</span></a></li>'),
	config: {
		"section": 				"statistics", //used for prefixing important elements such as #<section>-list
		"linkActiveClass": 		"active"
	},
	cache: {
		"activeCategoryId": null
	},
	
	/*
	* Handle linkClass and eventHandlers on category links
	*/
	init: function (options) {
		
		//merge options
		if (options) $.extend(dm.config, options);

		//Generate helper containers used for sliding effect
		dm._generateSlideContainer();

		/*
	 	* Prefill breadcrumb array with summary link and menu root link
	 	*/
		var $mainMenuLink = $("li a:first", dm.$categoriesContainer);
		dm.backlinksArray[0] = {
			"title": $mainMenuLink.find("span").text(),
			"nodeRef": $mainMenuLink[0].href
		}
		dm.backlinksArray[1] = {
			"title": $("li.root-menu:first", dm.$categoriesContainer).next().find("a:first span").text(),
			"nodeRef": dm.$categoriesContainer,
			"class": "root-menu"
		}

		/*
	 	*	Attach event handlers on relevant links
	 	*/
		$(".profile-sidebar-menu a").live("click", function(event) {

			if($(this).hasClass("active")) return false;

			/* init swipe for categories containing additional categories */
			if($(this).hasClass("has-submenu")) {
				dm._doSlide($(this).parent(), "in")
			} else if ($(this).hasClass("back-to")) {
				if(typeof $(this).data("nodeRef") == 'string') {
					window.location = $(this).data("nodeRef");
				} else {
					dm._doSlide($(this).data("nodeRef"), "out", $(this).data("index"))
				}
			} else { /* handle styling of simple links */
				$(".active", $(this).parents("ul"))
					.removeClass(dm.config.linkActiveClass);
				$(this).addClass(dm.config.linkActiveClass);
			}

			//if # in href, populate list on click and update location.hash
			if(this.href.indexOf("#") != -1) {
				if(!$(this).data("data-hash")) {
					$(this).data("data-hash", this.href.substring(this.href.indexOf("#")));
				}

				var categories = DynamicMenu._parseCategoryFromURL(this.href);
				DynamicMenu._populateList(categories[categories.length - 1]);
				location.hash = $(this).data("data-hash");
			}

			event.preventDefault();
		});
	},

	/*
	* Parse category info from url
	* @param string url
	* @return array
	*/
	_parseCategoryFromURL: function (url) {
		var hash = url.substring(url.lastIndexOf("#") + 1)
		return hash.split(":")
	},

	/*
	* Generates placeholder divs used for DOM node copying
	*/
	_generateSlideContainer: function () {
		var $swipeIn = $('<div/>', {
				id: "swipe-in-container",
				"class": "swipe-container"
			});

		var $swipeOut = $('<div/>', {
				id: "swipe-out-container",
				"class": "swipe-container"
		});

		var $ul = $('<ul/>', {
				"class": "profile-sidebar-menu"
			});

		$ul.clone().appendTo($swipeIn, $swipeOut)
		$("#profile-sidebar-menu").after($swipeIn, $swipeOut);

		dm.$swipeInContainer = $("#swipe-in-container");
		dm.$swipeOutContainer = $("#swipe-out-container");
	},

	/*
	* Generate back links
	* @param DOMelement (LI) listElement
	* @param string direction
	* @param string backIndex
	* TODO: Add caching to prevent repeated DOM node creation
	*/
	_generateBacklinks: function ($listElement, direction, backIndex) {
		var fragment 			= document.createDocumentFragment(),
			$list 				= $listElement.clone(),
			$backlink 			= null,
			$backlinkAnchor 	= null;

		if (direction == "in") {
			dm.backlinksArray.push({
				"nodeRef": $listElement,
				"title": $listElement.find("a:first").text()
			});
		} else {
			dm.backlinksArray = dm.backlinksArray.slice(0, backIndex + 1);
		}

		$list
			.find("a.active").removeClass(dm.config.linkActiveClass).end()
			.find("a.has-submenu:first")
			.removeClass("has-submenu").addClass(dm.config.linkActiveClass).end();

		/* TODO: rework to avoid for loop */
		for (var x = 0, len = dm.backlinksArray.length; x < len - 1; x++) {
			$backlink = dm.$backlinkHTML.clone();
			$backlink.find("span").text(dm.backlinksArray[x].title);
			$backlinkAnchor = $backlink.find("a");
			$backlinkAnchor
				.data("title", dm.backlinksArray[x].title)
				.data("index", x);
			if(dm.backlinksArray[x]["class"])
				$backlinkAnchor.addClass(dm.backlinksArray[x]["class"])

			if(typeof dm.backlinksArray[x].nodeRef == 'string') {
				$backlinkAnchor.attr("href", dm.backlinksArray[x].nodeRef)
			} else $backlinkAnchor.data("nodeRef", dm.backlinksArray[x].nodeRef)

			fragment.appendChild($backlink[0])
		}

		$("ul:first", dm.$swipeInContainer).empty().append(fragment, $list);

	},

	/*
	* Swipe between main categories and subcategories
	* @param DOMelement (LI) listElement
	* @param string direction
	* @param string backIndex
	* TODO: optimize slide animation
	*/
	_doSlide: function ($listElement, direction, backIndex) {

		var	inDirection 	= (direction == 'in') ? 'right' : 'left',
			outDirection 	= (direction == 'in') ? 'left' : 'right';

			dm._generateBacklinks($listElement, direction, backIndex);

		/* if clicked on back-to link for main list */
		if (dm.$categoriesContainer == $listElement) {
			dm.$swipeInContainer = dm.$categoriesContainer;
			$("> li a.active", dm.$categoriesContainer).removeClass(dm.config.linkActiveClass);
			$("> li.root-menu", dm.$categoriesContainer).next().find("a:first").addClass(dm.config.linkActiveClass);
			dm._populateList("summary");
		}

		if(dm.$categoriesContainer.is(":visible")) {
			dm.$categoriesContainer.hide("slide", { direction: outDirection }, 150, function () {
				dm.$swipeInContainer.show("slide", { direction: inDirection }, 150)
				dm.$swipeOutContainer = dm.$swipeInContainer;
			})
		} else {
			dm.$swipeOutContainer.hide("slide", { direction: outDirection }, 150, function () {
				dm.$swipeInContainer.show("slide", { direction: inDirection }, 150)
				dm.$swipeInContainer = dm.$swipeOutContainer;
			})
		}
	},

	/*
	* Scrolls to an list entry
	* @param string entryId 	i.e. "a726"
	*/
	_scrollToEntry: function (entryId) {
		var $listElement = $("#" + dm.config.section + "-list  li[data-id=" + entryId.substring(1) + "]");
		$listElement.addClass("showing");
		Profile.smoothScrollTo($listElement, 1000)
	},

	/*
	* Load category data via JSON and cache
	* @param int catId
	* @param int entryId
	*/
	_populateList: function (catId, entryId) {

		var url = window.location.pathname + "/" + catId,
			categoryExists = $("#cat-" + catId).length;

			dm.cache.activeCategoryId = catId;

			$(".search-container:first, .container").hide();

		if(categoryExists) {
			$("#cat-" + catId)[(catId == 'summary') ? "fadeIn" : "show"]();
			$(".search-container:first").toggle( (catId != 'summary') )
			if(entryId)
				dm._scrollToEntry(entryId)
		} else {

			$("#" + dm.config.section + "-list ").addClass("loading");

			setTimeout(function () {
				$.ajax({
					url: url,
					success: function (data) {
						$("#" + dm.config.section + "-list").removeClass("loading").append(data);
						$("#" + dm.config.section + "-list > div:last #cat-" + catId + ".container").show();
						$(".search-container:first, #" + dm.config.section + "-list > div:last").fadeIn("fast");

						if(entryId)
							dm._scrollToEntry(entryId)
					},
					dataType: "html"
				});
			}, 300)
		}

		$("#" + dm.config.section + "-search").val($("#" + dm.config.section + "-search").data("value"))
	}
}

var dm = DynamicMenu;

var Profile = {

	init: function() {
		$('#profile-sidebar-menu').delegate("a[href*='/armory']", 'mouseover', function() {

			var $this = $(this);
			var $tooltip = Wow.createSimpleTooltip($this.text(), MsgProfile.tooltip.armory.message);

			$tooltip.append($('<li/>').addClass('color-tooltip-green').text(MsgProfile.tooltip.armory.action))

			Tooltip.show(this, $tooltip);

		});

		$('#profile-info-realm').mouseover(function() {
			var $this = $(this);
			var battlegroup = $this.attr('data-battlegroup');
			if(battlegroup) {
				Tooltip.show(this, Wow.createSimpleTooltip($this.text(), battlegroup));
			}
		});
	},

	/* 
	* Smoothly scroll body to element's offset().top
	* @param string||object $element
	* @param int||string duration
	* @param function callback
	*/
	smoothScrollTo: function(element, duration, callback) {

		// Don't scroll if the element is already visible
		var top = $(element).offset().top;
		var $window = $(window);
		if(top >= $window.scrollTop() && top <= $window.scrollTop() + $window.height()) {
			return;
		}

		$($.browser.webkit ? 'body' : 'html').animate( { scrollTop: top - 10 }, duration || 333, callback || null);
	}

};

$(document).ready(Profile.init);